/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package proyectoia;

import IA.DistFS.Requests;
import IA.DistFS.Servers;
import IA.DistFS.Servers.WrongParametersException;
import aima.search.framework.Problem;
import aima.search.framework.Search;
import aima.search.framework.SearchAgent;
import aima.search.informed.SimulatedAnnealingSearch;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.NavigableSet;
import java.util.TreeSet;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jfree.ui.RefineryUtilities;

public class DistFileSystem {

    static LinkedBlockingDeque<Data> totalList = new LinkedBlockingDeque();

    public static void escriuPeticions(Requests requests) {
        for (int i = 0; i < requests.size(); i++) {
            System.out.println("Petició #" + i);
            int request[] = requests.getRequest(i);
            System.out.println("    Usuari: " + request[0] + " Fitxer: " + request[1]);
        }
    }

    public static void escriuSetID(NavigableSet<Integer> setID, String type) {
        //Iterator<TreeSet> user = users.descendingIterator();
        for (int id : setID) {
            System.out.println(type + " " + id);
        }
    }

    public static NavigableSet<Integer> obteUsuaris(Requests requests) {
        NavigableSet<Integer> usersID = new TreeSet();
        for (int i = 0; i < requests.size(); i++) {
            usersID.add(requests.getRequest(i)[0]);
        }
        return usersID;
    }

    public static NavigableSet<Integer> obteFitxers(Requests requests) {
        NavigableSet<Integer> filesID = new TreeSet();
        for (int i = 0; i < requests.size(); i++) {
            filesID.add(requests.getRequest(i)[1]);
        }
        return filesID;
    }

    private static void printResults(SearchAgent agent) {

        for (Object string : agent.getActions()) {
            String message = (String) string;

            String[] servers = message.split("#");
            for (int i = 0; i < servers.length; i++) {
                System.out.println("    " + servers[i]);
            }

            System.out.println("==================================================================");
        }
    }

    /**
     * @param args the command line arguments
     * @param args[1] Nombre de servidors
     * @param args[2] Nombre mínim de replicacions
     * @param args[3] Llavor de servidors
     * @param args[4] Nombre d'usuaris
     * @param args[5] Nombre màxim de peticions per usuari
     * @param args[6] Llavor de peticions
     */
    public static void yanomain(String[] args) throws WrongParametersException {
        
        
        Servers servers;
        Requests requests;
        NavigableSet<Integer> usersID;
        NavigableSet<Integer> filesID;
        
        Integer numServers, numReplications, serverSeed;
        Integer numUsers, numRequests, requestSeed;
        
        DistFileSystemState state;

        if (args.length != 7) {
            System.out.println("Nombre d'arguments invalid. Introdueix en aquest ordre:");
            System.out.println("    Nombre de servidors");
            System.out.println("    Nombre mínim de replicacions");
            System.out.println("    Llavor de servidors");
            System.out.println("    Nombre d'usuaris");
            System.out.println("    Nombre màxim de peticions per usuari");
            System.out.println("    Llavor de peticions");
            //return;    
            System.out.println("S'utilitzaran valors per defecte");
            
           numServers = 20;
           numReplications = 5;
           serverSeed = 78754;
           numUsers = 200;
           numRequests = 5;
           requestSeed = 2112;
        }
        else {
           numServers = Integer.parseInt(args[1]);
           numReplications = Integer.parseInt(args[2]);
           serverSeed = Integer.parseInt(args[3]);
           numUsers = Integer.parseInt(args[4]);
           numRequests = Integer.parseInt(args[5]);
           requestSeed = Integer.parseInt(args[6]);             
        }
        
        
//        Experiment1 exp1 = new Experiment1(10,0,"experiment1");
//        exp1.execute();
        
        
        try {
            
            servers = new Servers(numServers, numReplications, serverSeed);
            requests = new Requests(numUsers, numRequests, requestSeed);
            usersID = obteUsuaris(requests);
            filesID = obteFitxers(requests);

            state = new DistFileSystemState(servers, requests, numServers);
            state.generateGreedySolution();
           // state.print();
           
            Plotter plotter = new Plotter(totalList, numServers);
            plotter.pack();
            RefineryUtilities.centerFrameOnScreen(plotter);
            plotter.setVisible(true); 
            new Thread (plotter, "plotter" ).start();

            ArrayList<Data> data = new ArrayList();

            System.out.println(System.identityHashCode(state));
            Problem problem = new Problem(state,
                                          new DistFileSystemSuccessorFunction1(),
                                          new DistFileSystemGoalTest(),
                                          new DistFileSystemHeuristicFunction1());
            
            SimulatedAnnealingSearch search = new SimulatedAnnealingSearch(1000, 20,100, 0.005);
            search.traceOn();
            try {
                SearchAgent agent = new SearchAgent(problem,search);
                
                System.out.println(System.identityHashCode(agent.getActions().get(0)));
                
  
                //Plotter plotter = new Plotter();
                // new Thread ( new Plotter() , "Pepe").start();
                //new Thread ( new Plotter() , "Maria").start();
                //plotter.run();
                //printResults(agent);
                //escriuPeticions(requests);
            } catch (Exception ex) {
                Logger.getLogger(DistFileSystem.class.getName()).log(Level.SEVERE, null, ex);
            }
        }catch(Servers.WrongParametersException S)
        {
            System.out.println("=============================================");
            System.out.println("Exception!");
            System.out.println(S.getMessage());
        }

        /*
        
       /* CombinedXYPlotDemo1 demo = new CombinedXYPlotDemo1("hola", totalList);
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
        */

    }
}
